/**
 * 页面支持 增删改查 的能力的混入
 */
export default {
  data() {
    return {
      query: {},
      xdata: {
        _xcrud: {
          list: [],
          detail: {},
          query: {},
          paging: {
            pageIndex: 1,
            pageSize: 10,
            total: 1
          },
          parent: undefined,
          id: undefined,
          editing: false,
        },
      },
      xmeta: {
        _xcrud: {
          type: 'list'
        }
      }
    }
  },
  onLoad(query) {
    this.query = query
    this.xdata._xcrud.list = []
    this.xdata._xcrud.parent = query._xcrudParent
    this.xdata._xcrud.id = query._xcrudId
    this.xdata._xcrud.detail = query._xcrudDetail?JSON.parse(query._xcrudDetail):{}
    this.xdata._xcrud.editing = query._xcrudType==='create'||query._xcrudType==='update'
    if( query._xcrudType) this.xmeta._xcrud.type = query._xcrudType
  },
  // onReady () {
  //   return this._xcrudDoRefresh()
  // },
  onShow () {
    return this._xcrudDoRefresh()
  },
  onPullDownRefresh() {
    return this._xcrudDoRefresh()
  },
  // onReachBottom() {
  //   return this._xcrudDoMore()
  // },
  methods: {
    debug(...args) {
      console.log('xone',...args)
    },

    _xcrudGetXPath(data, path) {
      let xpath = path.split('.').filter(v=>v)
      for(let v of xpath) {
        if(!data) break
        data = data[v]
      }
      return data
    },

    _xcrudGetXMeta(xpath, options={}) {
      let xmeta = options.xbase
      let isRaw = options.isRaw
      let defaultValue = options.defaultValue
      let ret

      if(xpath) ret = this._xcrudGetXPath(xmeta, xpath)
      if((typeof ret==='function')&&!isRaw) ret = ret(xmeta)
      // fetch 形式
      // if(ret&&ret.xfetch&&!isRaw) {
      //   let option = ret
      //   let value = this.getXData(option.xfield, {xbase: option.xbase||'_xruntime'})
      //   if(value) {
      //     ret = value
      //   }else{
      //     option.xfetch&&option.xfetch(this).then(ret=>{
      //       this.setXData(option.xfield, ret, option.xbase||'_xruntime')
      //     })
      //     ret = ret.defaultValue||[]
      //   }
      // }

      return ret===undefined?options.defaultValue:ret
    },

    _xcrudAddPart(name) {
      this.$set(this.xmeta, '_xcrud'+name, {
        type: this.query._xcrudType||'list'
      })
      this.$set(this.xdata, '_xcrud'+name, {
        list: [],
        detail: this.query._xcrudDetail?JSON.parse(this.query._xcrudDetail):{},
        query: {},
        paging: {
          pageIndex: 1,
          pageSize: 10
        },
        parent: this.query._xcrudParent,
        id: this.query._xcrudId,
        editing: this.query._xcrudType==='create'||this.query._xcrudType==='update',
      })
    },
    
    _xcrudGetType(){
      return this.xmeta._xcrud.type
    },
    _xcrudGetList(index) {
      let list = this.xdata._xcrud.list || []
      return index!==undefined?list[index]:list
    },
    _xcrudSetList(list, part) {
      return this.xdata['_xcrud'+part].list = list||[]
    },
    _xcrudGetQuery(field) {
      let data = this.xdata._xcrud.query || []
      return field!==undefined?data[field]:data
    },
    _xcrudSetQuery(field, value, reset) {
      let data = reset?{}:(this.xdata._xcrud.query||{})
      if(typeof field==='string'){
        data[field] = value
      }else{
        Object.assign(data, field)
      }
      return this.xdata._xcrud.query = data
    },
    _xcrudGetPaging(field) {
      let data = this.xdata._xcrud.paging || []
      return field!==undefined?data[field]:data
    },
    _xcrudSetPaging(field, value, reset) {
      let data = reset?{}:(this.xdata._xcrud.paging||{})
      if(typeof field==='string'){
        data[field] = value
      }else{
        Object.assign(data, field)
      }
      return this.xdata._xcrud.paging = data
    },
    _xcrudGetDetail(field) {
      let data = this.xdata._xcrud.detail || []
      return field!==undefined?data[field]:data
    },
    _xcrudSetDetail(field, value, reset) {
      let data = reset?{}:{...this.xdata._xcrud.detail}
      if(typeof field==='string'){
        data[field] = value
      }else{
        Object.assign(data, field)
      }
      // return this.xdata._xcrud.detail = data
      return this.$set(this.xdata._xcrud, 'detail', data)
    },
    _xcrudGetParent() {
      return this.xdata._xcrud.parent
    },
    _xcrudSetParent(value) {
      return this.xdata._xcrud.parent = value
    },
    _xcrudGetId() {
      return this.xdata._xcrud.id
    },
    _xcrudSetId(value) {
      return this.xdata._xcrud.id = value
    },
    _xcrudGetEditing() {
      return this.xdata._xcrud.editing
    },
    _xcrudSetEditing(value) {
      return this.xdata._xcrud.editing = value
    },

    _xcrudToCreate(options) {
      let params = {
        ...this.query,
        _xcrudType: 'create',
        ...options||{}
      }
      // if(this.xmeta.xcrud.onBeforeToCreate&&this.xmeta.xcrud.onBeforeToCreate(params)) return
      this.$x.navigator.push('/'+this.route, params)
      // this.xmeta.xcrud.onToCreate&&this.xmeta.xcrud.onToCreate(params)
    },
    _xcrudToUpdate(data, options) {
      let params = {
        ...this.query,
        _xcrudType: 'update',
        _xcrudId: data.id,
        _xcrudDetail: JSON.stringify(data),
        ...options||{}
      }
      // if(this.xmeta.xcrud.onBeforeToUpdate&&this.xmeta.xcrud.onBeforeToUpdate(params)) return
      this.$x.navigator.push('/'+this.route, params)
      // this.xmeta.xcrud.onToUpdate&&this.xmeta.xcrud.onToUpdate(params)
    },
    _xcrudToSub(data, options) {
      let params = {
        _xcrudType: 'list',
        _xcrudParent: data[this.xmeta._xcrud['parentKey']||'id']
      }
      this.$x.navigator.push('/'+this.route, params)
    },

    _xcrudDoNetworkHandleParent(type, payload, data, part) {
      if(type==='list') {
        let xcrudParent = this._xcrudGetParent()
        if(xcrudParent) payload.data[this.xmeta._xcrud.parentId||'parentId'] = xcrudParent
      } else if(type==='create') {
        let xcrudParent = this._xcrudGetParent()
        if(xcrudParent) payload.data[this.xmeta._xcrud.parentId||'parentId'] = xcrudParent
      }
    },
    _xcrudDoNetworkHandleQuery(type, payload, data, part) {
      if(type==='list'){
        let query = this._xcrudGetQuery()
        Object.assign(payload.data, query)
      }
    },
    _xcrudDoNetworkHandlePaging(type, payload, data, part) {
      if(type==='list'){
        let paging = this._xcrudGetPaging()
        payload.data.pageIndex = paging.pageIndex
        payload.data.pageSize = paging.pageSize
      }
    },
    _xcrudDoNetworkHandleRule(type, payload, data, part) {

    },
    _xcrudDoNetworkHandleData(type, payload, data, part) {
      if(type==='create'||type==='update'||type==='submit') {
        let xfields = this.xmeta.xfields||[]
        if(xfields) {
          for(let meta of xfields) {
            let xsubmit = this._xcrudGetXMeta('xsubmit', {xbase: meta, isRaw: true})
            if(xsubmit===false) continue
            let xtitle = this._xcrudGetXMeta('xtitle', {xbase: meta}) 
            let xfield = this._xcrudGetXMeta('xfield', {xbase: meta}) 
            let dvalue = this._xcrudGetDetail(xfield)
            let xvalue = this._xcrudGetXMeta('xvalue', {xbase: meta})
            dvalue = xvalue || dvalue
            let xrule = this._xcrudGetXMeta('xrule', {xbase: meta, isRaw: true})
            let xruleMessage = this._xcrudGetXMeta('xruleMessage', {xbase: meta}) 
            let xruleMessageExtra = '不能为空'
            if(xrule===true) {
              let xrule0 = this._xcrudGetXMeta('xrule0', {xbase: meta})
              xrule = (value, meta)=>Boolean(value||(value===0&&xrule0))
            }else if(xrule==='number') {
              xrule = (value,meta)=>!isNaN(value)
              xruleMessageExtra = '需要是有效数字'
            }
            if(xrule&&!xrule(dvalue, meta)) {
              return xruleMessage||`${xtitle}${xruleMessageExtra}`
            }
  
            if(typeof xsubmit==='function') {
              let ret = xsubmit(dvalue, xfield)
              Object.assign(payload.data, ret)
            }else{
              payload.data[xfield] = dvalue
            }
          }
        }else{
          Object.assign(payload.data, this._xcrudGetXMeta())
        }
      }

      if(type==='delete') {
        let primaryKey = this.xmeta._xcrud.primaryKey||'id'
        payload.data[primaryKey] = data[primaryKey]
        payload.data.isDelete = 1
      }
    },
    _xcrudDoNetwork(type, data, part='') {
      this.debug('_xcrudDoNetwork', type, data, part)
      let payload = {
        url: this.xmeta._xcrud['url'+type]||'',
        params: this.xmeta._xcrud['params'+type]||{},
        data: this.xmeta._xcrud['data'+type]||{},
        method: this.xmeta._xcrud['method'+type]||((type==='list'||type==='detail')?'GET':'POST'),
      }

      this._xcrudDoNetworkHandleParent(type, payload, data, part)
      this._xcrudDoNetworkHandleQuery(type, payload, data, part)
      this._xcrudDoNetworkHandlePaging(type, payload, data, part)
      let checkData = this._xcrudDoNetworkHandleData(type, payload, data, part)
      if(checkData) { this.$x.notify.showToast(checkData); return Promise.reject() }
      this.debug('_xcrudDoNetwork', payload)
      if(this._xcrudDoNetworkBeforeRequest&&this._xcrudDoNetworkBeforeRequest(type, payload, data, part)) return Promise.resolve()
      let ret = this.$x.request(payload).then(res=>{
        if(this._xcrudDoNetworkBeforeResponse&&this._xcrudDoNetworkBeforeResponse(res, type, payload, data, part)) return Promise.resolve()
        
        if(type==='list') {
          let list = []
          if(this.xmeta['_xcrud'+part].canPaging!=false) {
            this._xcrudSetPaging({
              pageIndex: res.data.current,
              pageSize: res.data.size,
              total: res.data.total,
            })
            list = list.concat(res.data.records)
          }else{
            list = list.concat(res.data)
          }
          this._xcrudSetList(list, part)
        } else if(type==='detail') {
          this._xcrudSetDetail(res.data)
        } else if(type==='create') {
          this.$x.notify.showToast('添加成功')
          this.$x.navigator.back()
        } else if(type==='update') {
          this.$x.notify.showToast('修改成功')
          this.$x.navigator.back()
        } else if(type==='delete') {
          this.$x.notify.showToast('删除成功')
          this._xcrudDoRefresh()
        }
        
        if(this._xcrudDoNetworkAfterResponse&&this._xcrudDoNetworkAfterResponse(res, type, payload, data, part)) return Promise.resolve()
      })
      return ret
    },

    _xcrudDoRefresh(data, part) {
      let type = this._xcrudGetType(part)
      if(type==='list') {
        setTimeout(()=>{
          this._xcrudSetPaging('pageIndex', 1)
          return this._xcrudDoList(undefined, part)
        }, 100)
      } if(type==='detail') {
        return this._xcrudDoDetail(undefined, part)
      } else if(type==='update'&&this.xmeta._xcrud.updateByDetail) {
        return this._xcrudDoDetail(undefined, part)
      }else {
        return Promise.resolve()
      }
    },
    _xcrudDoMore(index, part) {
      let type = this._xcrudGetType(part)
      if(type!=='list'||this.xmeta._xcrud.canPaging===false) return
      let list = this._xcrudGetList(undefined, part)
      let pagging = this._xcrudGetPaging(undefined, part)
      if(list.length>=pagging.total) return
      if(index === undefined) index = pagging.pageIndex+1
      this._xcrudSetPaging('pageIndex', index) 
      return this._xcrudDoList(undefined, part)
    },
    _xcrudDoCreate(data, part) {
      return this._xcrudDoNetwork('create', data, part)
    },
    _xcrudDoList(data, part) {
      return this._xcrudDoNetwork('list', data, part)
    },
    _xcrudDoDetail(data, part) {
      return this._xcrudDoNetwork('detail', data, part)
    },
    _xcrudDoUpdate(data, part) {
      return this._xcrudDoNetwork('update', data, part)
    },
    _xcrudDoDelete(data, part) {
      return this._xcrudDoNetwork('delete', data, part)
    },
    _xcrudDoSubmit(data, part) {
      return this._xcrudDoNetwork('submit', data, part)
    },
  }
}